<?php

function encrypt($data, $key = null, $expire = null)
{
    $key = $key == null ? config('token.key') : (string) $key;
    $expire = $expire == null ? config('token.expire') : (int) $expire;
    $key = sha1($key);
    $data = base64_encode($data);
    $x = 0;
    $len = strlen($data);
    $l = strlen($key);
    $char = '';
    for ($i = 0; $i < $len; $i++) {
        if ($x == $l) $x = 0;
        $char .= substr($key, $x, 1);
        $x++;
    }
    $str = sprintf('%010d', $expire ? $expire + time() : 0);
    for ($i = 0; $i < $len; $i++) {
        $str .= chr(ord(substr($data, $i, 1)) + (ord(substr($char, $i, 1))) % 256);
    }
    $str = base64_encode($str);
    $str = str_replace(array('=', '+', '/'), array('O0O0O', 'o000o', 'oo00o'), $str);
    return $str;
}

function decrypt($data, $key = null, $keep = true)
{
    //优先尝试解密有限次数的缓存结果
    // $cached = cache($data);
    // if ($cached && is_array($cached)) {
    //     $decode_data = $cached[0];
    //     $decode_num = $cached[1];
    //     if ($decode_num >= 1) {
    //         $decode_num -= 1;
    //         if (!$keep) cache($data, [$decode_data, $decode_num]);
    //         return $decode_data;
    //     } else {
    //         cache($data, null);
    //         return null;
    //     }
    // }
    //有限时间解密
    $key = $key == null ? config('token.key') : $key;
    $data = str_replace(array('O0O0O', 'o000o', 'oo00o'), array('=', '+', '/'), $data);
    $key = sha1($key);
    $x = 0;
    $data = base64_decode($data);
    $expire = substr($data, 0, 10);
    $data = substr($data, 10);
    if ($expire > 0 && $expire < time()) {
        return null;
    }
    $len = strlen($data);
    $l = strlen($key);
    $char = $str = '';
    for ($i = 0; $i < $len; $i++) {
        if ($x == $l) $x = 0;
        $char .= substr($key, $x, 1);
        $x++;
    }
    for ($i = 0; $i < $len; $i++) {
        if (ord(substr($data, $i, 1)) < ord(substr($char, $i, 1))) {
            $str .= chr((ord(substr($data, $i, 1)) + 256) - ord(substr($char, $i, 1)));
        } else {
            $str .= chr(ord(substr($data, $i, 1)) - ord(substr($char, $i, 1)));
        }
    }
    return base64_decode($str);
}